-
Notifications
You must be signed in to change notification settings - Fork 0
Window wrapper #24
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Window wrapper #24
Conversation
WalkthroughCentralized window lifecycle in GpuWrapper via lazy acquire_window(); made PipelineWrapper non-copyable and moved its constructor to private; replaced optional pipeline and removed raw SDL_Window* from UserApp, updating main.cpp to use concrete PipelineWrapper and gpu_wrapper->acquire_window() calls. Changes
Sequence Diagram(s)sequenceDiagram
participant App as UserApp
participant Gpu as GpuWrapper
participant Pipe as PipelineWrapper
participant SDL as SDL/GPU
App->>Gpu: create GpuWrapper(shared_ptr)
App->>Pipe: construct PipelineWrapper(Gpu) %% direct concrete construction
App->>Pipe: set_vertex_shader(src)
App->>Gpu: acquire_window()
alt first acquire
Gpu->>SDL: SDL_CreateWindow()
Gpu->>SDL: SDL_ClaimWindowForGPUDevice()
Gpu->>Gpu: store m_window
end
Gpu-->>App: window handle
App->>Gpu: get_texture_format(window) %% uses acquire_window internally
App->>Pipe: submit()
Pipe->>SDL: submit pipeline to GPU
App->>App: shutdown
Pipe->>SDL: pipeline teardown
Gpu->>SDL: SDL_ReleaseWindowFromGPUDevice()
Gpu->>SDL: SDL_DestroyWindow()
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes
Possibly related PRs
Poem
Pre-merge checks and finishing touches✅ Passed checks (3 passed)
✨ Finishing touches🧪 Generate unit tests (beta)
📜 Recent review detailsConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro 📒 Files selected for processing (1)
🚧 Files skipped from review as they are similar to previous changes (1)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (10)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
|
Here's the code health analysis summary for commits Analysis Summary
|
|
clang-tidy review says "All clean, LGTM! 👍" |
1 similar comment
|
clang-tidy review says "All clean, LGTM! 👍" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
♻️ Duplicate comments (1)
main.cpp (1)
28-28: Concrete PipelineWrapper member simplifies usage; ensure copy/move semantics are as intendedSwitching from an
optionalto a concretesopho::PipelineWrapperconstructed viagpu_wrapper->create_pipeline()and then using it directly ininit()/iterate()is a nice simplification—no morehas_value()/->indirection and the pipeline is always initialized before use.Given that
PipelineWrapperis returned by value fromGpuWrapper::create_pipeline()and owns GPU resources, this pattern relies on the copy/move behavior ofPipelineWrapper. To avoid surprises, it’s worth aligning this with the suggestion insdl_wrapper/sdl_wrapper.pipeline.ixx(explicitly delete copies and, if needed, enable moves) and then ensuring you don’t inadvertently copypipeline_wrapperelsewhere.Once you lock down those semantics in the wrapper type, the usage here is straightforward and robust.
Also applies to: 74-76, 154-154, 163-163, 195-195
🧹 Nitpick comments (4)
sdl_wrapper/sdl_wrapper.gpu.ixx (2)
8-8: Window member and teardown ordering look good; add a small guard for robustnessThe added
SDL_Window* m_windowplus inclusion of the video header and the destructor’s order of operations (release-from-device, then destroy window, then destroy device) are all sensible and keep window/device lifetimes consistent.To be a bit more defensive in failure cases (e.g. device creation failed but a window was somehow created later), consider guarding the release call on
m_deviceas well, mirroring the laterif (m_device):~GpuWrapper() { if (m_window) { - SDL_ReleaseWindowFromGPUDevice(m_device, m_window); + if (m_device) + { + SDL_ReleaseWindowFromGPUDevice(m_device, m_window); + } SDL_DestroyWindow(m_window); } if (m_device) { SDL_DestroyGPUDevice(m_device); } m_device = nullptr; }This keeps behavior unchanged in the normal path while avoiding calling SDL with a null device pointer in edge cases.
Also applies to: 19-21, 31-37
74-82: Tighten acquire_window() API surface (return by value instead of non-const reference)
acquire_window()currently returns a non-const reference to the internalSDL_Window*, which lets callers accidentally reassignm_windowand break invariants insideGpuWrapper.You can keep behavior identical while tightening encapsulation by returning the pointer by value:
- auto& acquire_window() + SDL_Window* acquire_window() { if (!m_window) { m_window = SDL_CreateWindow("Hello, Triangle!", 960, 540, SDL_WINDOW_RESIZABLE); SDL_ClaimWindowForGPUDevice(m_device, m_window); } return m_window; }Call sites that currently pass
gpu_wrapper->acquire_window()to SDL/ImGui APIs will continue to compile unchanged.sdl_wrapper/sdl_wrapper.pipeline.ixx (1)
29-40: Constructor access restriction is good; consider making PipelineWrapper explicitly non-copyable (or move-only)Making the
PipelineWrapper(std::shared_ptr<GpuWrapper>)constructor private and friendingGpuWrappernicely centralizes pipeline creation in the GPU wrapper.However, with only a user-defined destructor and no explicit copy/move declarations,
PipelineWrapperis still copyable by default while move operations are suppressed. IfPipelineWrapperowns theSDL_GPUGraphicsPipeline*and releases it in the destructor, accidental copies could lead to subtle lifetime issues.Consider making ownership explicit, e.g.:
class PipelineWrapper { SDL_GPUGraphicsPipeline* m_graphics_pipeline{}; std::shared_ptr<GpuWrapper> m_device{}; // ... bool m_modified = false; PipelineWrapper(std::shared_ptr<GpuWrapper> p_device); public: + PipelineWrapper(const PipelineWrapper&) = delete; + PipelineWrapper& operator=(const PipelineWrapper&) = delete; + + PipelineWrapper(PipelineWrapper&&) = default; + PipelineWrapper& operator=(PipelineWrapper&&) = default;This keeps construction restricted to
GpuWrapperwhile preventing accidental copies and allowing move semantics if you need them later.main.cpp (1)
104-104: Good use of acquire_window(); consider also using GpuWrapper::get_texture_format()Routing ImGui and swapchain acquisition through
gpu_wrapper->acquire_window()nicely reflects the new window ownership model inGpuWrapperand avoids carrying a rawSDL_Window*inUserApp.Since
GpuWrappernow exposesget_texture_format(), you can also avoid duplicating the device+window pairing logic when settinginit_info.ColorTargetFormat:- ImGui_ImplSDL3_InitForSDLGPU(gpu_wrapper->acquire_window()); - ImGui_ImplSDLGPU3_InitInfo init_info = {}; - init_info.Device = gpu_wrapper->data(); - init_info.ColorTargetFormat = - SDL_GetGPUSwapchainTextureFormat(gpu_wrapper->data(), gpu_wrapper->acquire_window()); + ImGui_ImplSDL3_InitForSDLGPU(gpu_wrapper->acquire_window()); + ImGui_ImplSDLGPU3_InitInfo init_info = {}; + init_info.Device = gpu_wrapper->data(); + init_info.ColorTargetFormat = gpu_wrapper->get_texture_format();The later
SDL_WaitAndAcquireGPUSwapchainTexture(commandBuffer, gpu_wrapper->acquire_window(), ...)call already cleanly uses the wrapper, so this keeps all swapchain/window handling consistently funneled throughGpuWrapper.Also applies to: 107-108, 171-172
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (3)
main.cpp(6 hunks)sdl_wrapper/sdl_wrapper.gpu.ixx(4 hunks)sdl_wrapper/sdl_wrapper.pipeline.ixx(1 hunks)
🧰 Additional context used
🧠 Learnings (4)
📓 Common learnings
Learnt from: WSQS
Repo: WSQS/sdl_test PR: 7
File: sdl_wrapper/sdl_wrapper.gpu.ixx:73-76
Timestamp: 2025-11-14T00:45:09.377Z
Learning: In sdl_wrapper/sdl_wrapper.gpu.ixx, validation for m_window in the GpuWrapper::get_texture_formate() method (checking if m_window is nullptr before calling SDL_GetGPUSwapchainTextureFormat) is deferred to a future window wrapper implementation and should not be flagged in reviews.
Learnt from: WSQS
Repo: WSQS/sdl_test PR: 7
File: sdl_wrapper/sdl_wrapper.gpu.ixx:37-43
Timestamp: 2025-11-13T11:35:48.273Z
Learning: In sdl_wrapper/sdl_wrapper.gpu.ixx, null pointer validation for the GpuWrapper::create_buffer method (checking m_device, SDL_CreateGPUBuffer return value, and shared_from_this() validity) is deferred to a future issue and should not be flagged in reviews.
Learnt from: WSQS
Repo: WSQS/sdl_test PR: 7
File: sdl_wrapper/sdl_wrapper.buffer.ixx:0-0
Timestamp: 2025-11-13T11:34:32.714Z
Learning: In sdl_wrapper/sdl_wrapper.buffer.ixx, null pointer validation for the BufferWrapper constructor (checking p_gpu, p_gpu->data(), and SDL_CreateGPUBuffer return value) is deferred to a future issue and should not be flagged in reviews.
Learnt from: WSQS
Repo: WSQS/sdl_test PR: 7
File: sdl_wrapper/sdl_wrapper.gpu.ixx:0-0
Timestamp: 2025-11-13T02:58:26.859Z
Learning: The sdl_wrapper library (in the repository WSQS/sdl_test) does not allow throwing exceptions. Error handling must use return codes, validity checks, or other non-exception mechanisms.
📚 Learning: 2025-11-14T00:45:09.377Z
Learnt from: WSQS
Repo: WSQS/sdl_test PR: 7
File: sdl_wrapper/sdl_wrapper.gpu.ixx:73-76
Timestamp: 2025-11-14T00:45:09.377Z
Learning: In sdl_wrapper/sdl_wrapper.gpu.ixx, validation for m_window in the GpuWrapper::get_texture_formate() method (checking if m_window is nullptr before calling SDL_GetGPUSwapchainTextureFormat) is deferred to a future window wrapper implementation and should not be flagged in reviews.
Applied to files:
main.cppsdl_wrapper/sdl_wrapper.pipeline.ixxsdl_wrapper/sdl_wrapper.gpu.ixx
📚 Learning: 2025-11-13T11:35:48.273Z
Learnt from: WSQS
Repo: WSQS/sdl_test PR: 7
File: sdl_wrapper/sdl_wrapper.gpu.ixx:37-43
Timestamp: 2025-11-13T11:35:48.273Z
Learning: In sdl_wrapper/sdl_wrapper.gpu.ixx, null pointer validation for the GpuWrapper::create_buffer method (checking m_device, SDL_CreateGPUBuffer return value, and shared_from_this() validity) is deferred to a future issue and should not be flagged in reviews.
Applied to files:
main.cppsdl_wrapper/sdl_wrapper.pipeline.ixxsdl_wrapper/sdl_wrapper.gpu.ixx
📚 Learning: 2025-11-13T11:34:32.714Z
Learnt from: WSQS
Repo: WSQS/sdl_test PR: 7
File: sdl_wrapper/sdl_wrapper.buffer.ixx:0-0
Timestamp: 2025-11-13T11:34:32.714Z
Learning: In sdl_wrapper/sdl_wrapper.buffer.ixx, null pointer validation for the BufferWrapper constructor (checking p_gpu, p_gpu->data(), and SDL_CreateGPUBuffer return value) is deferred to a future issue and should not be flagged in reviews.
Applied to files:
main.cppsdl_wrapper/sdl_wrapper.pipeline.ixxsdl_wrapper/sdl_wrapper.gpu.ixx
🔇 Additional comments (1)
sdl_wrapper/sdl_wrapper.gpu.ixx (1)
84-87: get_texture_format() correctly funnels through acquire_window()Routing
get_texture_format()throughacquire_window()ensures a window is created/claimed on first use before querying the swapchain texture format, which matches the new ownership model.No behavioral issues here from the wrapper’s perspective.
|
Note Unit test generation is an Early Access feature. Expect some limitations and changes as we gather feedback and continue to improve it. Generating unit tests... This may take up to 20 minutes. |
|
Caution The CodeRabbit agent failed during execution: Clone operation failed |
|
clang-tidy review says "All clean, LGTM! 👍" |
Summary by CodeRabbit